using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Xml.Serialization;
using System.Runtime.Serialization;

namespace Shrapnel
{
	/// <summary>
	/// A container class for a set of elements that all should be on the same visual
	/// layer.
	/// </summary>
	[DataContract()]
	public class Layer : ICollection<Element>, IList<Element>
	{
		/// <summary>
		/// The elements placed on this layer
		/// </summary>
		[DataMember(Name="Elements")]
		private List<Element> elements = new List<Element>();



		/// <summary>
		/// Draw our layer of elements
		/// </summary>
		/// <param name="graphics">Graphics object to use</param>
		/// <param name="viewState">ViewState to use</param>
		public void Draw(Graphics graphics, ViewState viewState)
		{
			BoundingBox viewFrustum = viewState.GetWorldBoundingBox();

			foreach (Element element in elements)
			{
				// View culling by checking the Area against our view.
				// This should speed up things... in theory.


				if (element.OverlapsWith(viewFrustum))
				{
					element.Draw(graphics, viewState);
				}				
			}
		}

		#region ICollection<Element> Members

		public void Add(Element item)
		{
			elements.Add(item);
			item.ParentLayer = this;
		}

		public void Clear()
		{
			foreach (Element element in elements)
			{
				element.ParentLayer = null;
			}
			elements.Clear();
		}

		public bool Contains(Element item)
		{
			return elements.Contains(item);
		}

		public void CopyTo(Element[] array, int arrayIndex)
		{
			elements.CopyTo(array, arrayIndex);
		}

		public int Count
		{
			get { return elements.Count; }
		}

		public bool IsReadOnly
		{
			get { return false; }
		}

		public bool Remove(Element item)
		{
			if (elements.Remove(item))
			{
				item.ParentLayer = null;
				return true;
			} else 
			{
				return false;
			}
		}

		#endregion

		#region IEnumerable<Element> Members

		public IEnumerator<Element> GetEnumerator()
		{
			return elements.GetEnumerator();
		}

		#endregion

		#region IEnumerable Members

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return elements.GetEnumerator();
		}

		#endregion

		#region IList<Element> Members

		public int IndexOf(Element item)
		{
			return elements.IndexOf(item);
		}

		public void Insert(int index, Element item)
		{
			elements.Insert(index, item);
			item.ParentLayer = this;
		}

		public void RemoveAt(int index)
		{
			if (index >= 0 && index < elements.Count)
			{
				elements[index].ParentLayer = null;
				elements.RemoveAt(index);
			}
		}

		public Element this[int index]
		{
			get
			{
				return elements[index];
			}
			set
			{
				elements[index] = value;
				value.ParentLayer = this;
			}
		}

		#endregion
	}
}
